import axios from 'axios'
import type {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  InternalAxiosRequestConfig
} from 'axios'
// 定义局部拦截器的函数类型
export interface RequestInterceptors<T = AxiosResponse> {
  // 请求拦截
  requestInterceptors?: (
    config: InternalAxiosRequestConfig
  ) => InternalAxiosRequestConfig
  // 错误请求拦截
  requestInterceptorsCatch?: (err: any) => any
  // 响应拦截
  responseInterceptors?: (config: T) => T
  // 相应错误请求拦截
  responseInterceptorsCatch?: (err: any) => any
}
// 自定义局部拦截器
export interface RequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: RequestInterceptors<T>
}
class Axios {
  instance: AxiosInstance
  constructor(config: RequestConfig) {
    this.instance = axios.create(config)
    // 全局请求拦截拦截
    this.instance.interceptors.request.use(
      (res) => {
        console.log('全局请求拦截')
        return res
      },
      (err) => {
        console.log(err)
      }
    )
    // 全局响应拦截
    this.instance.interceptors.response.use(
      (res) => {
        // 因为我们接口的数据都在res.data下，所以我们直接返回res.data
        console.log('全局响应拦截')
        return res.data.data
      },
      (err) => {
        console.log(err)
      }
    )
    // 局部拦截
    /*
      先判断参数有没有config有没有 interceptors属性 
      如果存在就需进行局部拦截
    */
    if (config.interceptors) {
      this.instance.interceptors.request.use(
        // 局部拦截 请求拦截
        config.interceptors.requestInterceptors,
        config.interceptors.requestInterceptorsCatch
      ),
        // 局部响应拦截
        this.instance.interceptors.response.use(
          config.interceptors.responseInterceptors,
          config.interceptors.responseInterceptorsCatch
        )
    }
  }
  request<T = any>(config: RequestConfig<T>) {
    if (config.interceptors?.requestInterceptors) {
      config = config.interceptors.requestInterceptors(config as any)
    }
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          if (config.interceptors?.responseInterceptors) {
            res = config.interceptors.responseInterceptors(res)
          }
          resolve(res)
        })
        .catch((err) => reject(err))
    })
  }
}

export default Axios
